package com.framework.plm.bas.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;

import com.framework.plm.bas.exception.PlmBasException;

public class UtilHttp {

	private HttpClient httpClient = null;
	private Header[] headers = null;
	private Cookie cookie = null;
	private String url = null;
	/**
	 * post请求的参数
	 */
	private Map<String, String> map = new HashMap<String, String>();
	private UtilHttp() {
		super();
	}
	public static UtilHttp getInstance(){
		UtilHttp utilHttp = new UtilHttp();
		utilHttp.setHttpClient(new HttpClient());
		return utilHttp;
	}
	public static UtilHttp getInstance(String url){
		UtilHttp utilHttp = new UtilHttp();
		utilHttp.setHttpClient(new HttpClient());
		utilHttp.setUrl(url);
		return utilHttp;
	}
	public static UtilHttp getInstance(String url, Header[] headers, Cookie cookie, Map<String, String> map){
		UtilHttp utilHttp = new UtilHttp();
		utilHttp.setHttpClient(new HttpClient());
		utilHttp.setCookie(cookie);
		utilHttp.setHeaders(headers);
		utilHttp.setMap(map);
		return utilHttp;
	}
	/**
	 * 通过httpClient的post方法请求数据
	 * @return String 假如成功：返回接受到的数据，否则返回出错状态码
	 */
	public String getContentByPost(String charSet) throws PlmBasException {
		HttpMethod post = getPostMethod(map,charSet);
		String str = "";
		try {
			httpClient.executeMethod(post);
			int statuscode = post.getStatusCode();
			if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) || (statuscode == HttpStatus.SC_MOVED_PERMANENTLY) || (statuscode == HttpStatus.SC_SEE_OTHER)
					|| (statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
				// 读取新的URL地址
				Header header = post.getResponseHeader("location");
				if (header != null) {
					String newuri = header.getValue();
					if ((newuri == null) || (newuri.equals("")))
						newuri = "/";
					this.setUrl(newuri);
					str=getContentByPost(charSet);
					return str;
				} 
			}else if(statuscode==HttpStatus.SC_OK){
				byte[] responseBody = post.getResponseBody();
				if (charSet == null) {
					str = new String(responseBody, "gb2312");
				} else {
					str = new String(responseBody, charSet);
				}
			}else{
				str=String.valueOf(statuscode);
			}
		} catch (HttpException e) {
		} catch (IOException e) {
		}finally {
			// 释放连接
			post.releaseConnection();
		}
		return str;
	}
	
	/**
	 * 通过httpClient的post方法请求数据以数据流方式返回
	 * @return String 假如成功：返回接受到的数据，否则返回出错状态码
	 */
	public String getContentByPostStream(String charSet) {
		HttpMethod post = getPostMethod(map,charSet);
		
		String str = "";
		try {
			httpClient.executeMethod(post);
			
			int statuscode = post.getStatusCode();
			if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) || (statuscode == HttpStatus.SC_MOVED_PERMANENTLY) || (statuscode == HttpStatus.SC_SEE_OTHER)
					|| (statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
				// 读取新的URL地址
				Header header = post.getResponseHeader("location");
				if (header != null) {
					String newuri = header.getValue();
					if ((newuri == null) || (newuri.equals("")))
						newuri = "/";
					this.setUrl(newuri);
					str=getContentByPostStream(charSet);
					return str;
				} 
			}else if(statuscode==HttpStatus.SC_OK){
				InputStream resStream = post.getResponseBodyAsStream();   
				BufferedReader br = new BufferedReader(new InputStreamReader(resStream,charSet));   
				StringBuffer resBuffer = new StringBuffer();   
				String resTemp = "";   
				while((resTemp = br.readLine()) != null){   
					resBuffer.append(resTemp);   
				}   
				str = resBuffer.toString();  
			}else{
				str=String.valueOf(statuscode);
			}
		} catch (HttpException e) {
		} catch (IOException e) {
		}finally {
			// 释放连接
			post.releaseConnection();
		}
		return str;
	}
	/**
	 * 通过httpClient的get方法请求
	 * @param charSet:example :"utf-8" 返回数据的编码
	 * @return String 如果请求成功：返回接受到的数据；否则返回出错状态码
	 */
	public String getContentByGet(String charSet) {
		HttpMethod getMethod = getGetMethod(url);
		String str = "";
		// 使用系统提供的默认的恢复策略
		getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
		try {
			int statusCode = httpClient.executeMethod(getMethod);
			if ((statusCode == HttpStatus.SC_MOVED_TEMPORARILY) ||
			(statusCode == HttpStatus.SC_MOVED_PERMANENTLY) ||
			(statusCode == HttpStatus.SC_SEE_OTHER) ||
			(statusCode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
				// 读取新的URL地址
				Header header = getMethod.getResponseHeader("location");
				if (header != null) {
					String newuri = header.getValue();
					if ((newuri == null) || (newuri.equals("")))
						newuri = "/";
					this.setUrl(newuri);
					str=this.getContentByGet(charSet);
					return str;
				}
			}else if(statusCode==HttpStatus.SC_OK){
				byte[] responseBody = getMethod.getResponseBody();
				if (charSet != null) {
					str = new String(responseBody, charSet);
				} else {
					str = new String(responseBody, "gb2312");
				}
			}else{
				str=String.valueOf(statusCode);
			}
		} catch (HttpException e) {} 
		  catch (IOException e) {	} 
		finally {
			// 释放连接
			getMethod.releaseConnection();
		}
		return str;
	}
	/**
	 * 得到返回的内容以字节形式
	 * @return
	 */
	public byte[] GetContentByte() {
		// 创建GET方法的实例
		GetMethod getMethod = new GetMethod(url);
		byte[] responseBody=null;
		// 使用系统提供的默认的恢复策略
		getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
		try {
			// 执行getMethod
			int statusCode = httpClient.executeMethod(getMethod);
			if ((statusCode == HttpStatus.SC_MOVED_TEMPORARILY) ||(statusCode == HttpStatus.SC_MOVED_PERMANENTLY) ||
					(statusCode == HttpStatus.SC_SEE_OTHER) ||(statusCode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
						// 读取新的URL地址
						Header header = getMethod.getResponseHeader("location");
						if (header != null) {
							String newuri = header.getValue();
							if ((newuri == null) || (newuri.equals("")))
								newuri = "/";
							this.setUrl(newuri);
							responseBody=this.GetContentByte();
							return responseBody;
						}
					}else if(statusCode==HttpStatus.SC_OK){
						responseBody = getMethod.getResponseBody();
					}else{
						responseBody=null;
					}
			return responseBody;
		} catch (HttpException e) {
			// 发生异常，可能是协议不对或者返回的内容有问题
			System.out.println("Please check your provided http address!");
			e.printStackTrace();
		} catch (IOException e) {
			// 发生网络异常
			e.printStackTrace();
		} finally {
			// 释放连接
			getMethod.releaseConnection();
		}
		return null;
	}
	
	/**
	 * 通过httpClient的get方法请求
	 * @param sslUrl example:"https://127.0.0.1:8443/ts/"
	 * @return String 假如成功：返回接受到的数据，否则返回出错状态码
	 */
	public String getSSLByGet(String sslUrl,String charSet) {
		HttpMethod getMethod = getGetMethod(sslUrl);
		String str = "";
		// 使用系统提供的默认的恢复策略
		getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
		try {
			int statusCode = httpClient.executeMethod(getMethod);
			if (statusCode != HttpStatus.SC_OK) {
				System.err.println("Method failed: " + getMethod.getStatusLine());
			}
			int statuscode = getMethod.getStatusCode();
			if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) ||
					(statuscode == HttpStatus.SC_MOVED_PERMANENTLY) ||
					(statuscode == HttpStatus.SC_SEE_OTHER) ||
					(statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
				// 读取新的URL地址
				Header header = getMethod.getResponseHeader("location");
				if (header != null) {
					String newuri = header.getValue();
					if ((newuri == null) || (newuri.equals("")))
						newuri = "/";
					this.setUrl(newuri);
					str=this.getSSLByGet(sslUrl, charSet);
					return str;
				} 
			}else if(statusCode==HttpStatus.SC_OK){
				byte[] responseBody = getMethod.getResponseBody();
				if (charSet != null) {
					str = new String(responseBody, charSet);
				} else {
					str = new String(responseBody, "gb2312");
				}
			}else{
				str=String.valueOf(statusCode);
			}
		} catch (HttpException e) {
		} catch (IOException e) {
		} finally {
			getMethod.releaseConnection();
		}
		return str;
	}

	/**
	 * 使用httpClient的GET方式提交数据 getParam
	 * @return
	 */
	public HttpMethod getGetMethod(String getParam) {
		return new GetMethod(getParam);
	}

	/**
	 * 封装httpClient的POST方式提交数据
	 * @param
	 * @return
	 */
	public HttpMethod getPostMethod(Map<String, String> param,String charset) {
		int i = 0;
		PostMethod post = new CharsetPostMethod(url,charset);
		if (headers != null) {
			for (int j = 0; j < headers.length; j++) {
				post.setRequestHeader(headers[j]);
			}
		}
		Iterator<String> keys = param.keySet().iterator();
		if (param != null) {
			NameValuePair[] nvp = new NameValuePair[param.size()];
			while (keys.hasNext()) {
				String key = keys.next();
				String value = param.get(key);
				NameValuePair simcard = new NameValuePair(key, value);
				nvp[i++] = simcard;
			}
			post.setRequestBody(nvp);
			return post;
		}
		return null;
	}
	
	public void setTimeOut(int time){
		httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(time);
	}
	
	public HttpClient getHttpClient() {
		return httpClient;
	}
	public void setHttpClient(HttpClient httpClient) {
		this.httpClient = httpClient;
	}
	public Header[] getHeaders() {
		return headers;
	}
	public void setHeaders(Header[] headers) {
		this.headers = headers;
	}
	public Cookie[] getCookies() {
		Cookie[] cookies = httpClient.getState().getCookies();

		return cookies;
	}
	public Cookie getCookie() {
		return cookie;
	}
	public String getCookieValue(String cookieName) {
		Cookie[] cookies = httpClient.getState().getCookies();
		String value = "";
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				String name = cookie.getName();
				if (cookieName != null && cookieName.equals(name)) {
					value = cookie.getValue();
					// System.out.println(cookie.getValue());
				}
			}
		}
		return value;
	}
	public String getSessionCookieValue() {
		Cookie[] cookies1 = httpClient.getState().getCookies();
		String httpSessionId = "";
		for (Cookie cookie : cookies1) {
			String cookieName = cookie.getName();
			if ("JSESSIONID".equals(cookieName)) {
				httpSessionId = cookie.getValue();
				// System.out.println(cookie.getValue());
			}
		}
		return httpSessionId;
	}
	
	public static class CharsetPostMethod extends PostMethod{
		private String CHARSET="UTF-8";
        public CharsetPostMethod(String url,String charset){
            super(url);
            setRequestCharSet(charset);
        }
        @Override
        public String getRequestCharSet() {
            //return super.getRequestCharSet();
            return CHARSET;
        }
        public void setRequestCharSet(String charset) {
        	//return super.getRequestCharSet();
        	this.CHARSET=charset;
        }
    }
	
	public void setCookie(Cookie cookie) {
		this.cookie = cookie;
	}
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public Map<String, String> getMap() {
		return map;
	}
	public void setMap(Map<String, String> map) {
		this.map = map;
	}
}
